package com.seari.custody.component;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.seari.custody.exception.BIZException;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.InputStream;

/**
 * @author lxv1
 */
@Slf4j
@Component
@Configuration
@EnableConfigurationProperties({MinIoProperties.class})
public class MinIoUtil {
    public final static String MEETING_BUCKET = "meeting";
    public final static String TEST_BUCKET = "test";

    private MinIoProperties minIo;

    public MinIoUtil(MinIoProperties minIo) {
        this.minIo = minIo;
    }

    private MinioClient instance;

    @PostConstruct
    public void init() {
        try {
            instance = new MinioClient(minIo.getUrl(), minIo.getAccessKey(), minIo.getSecretKey());
        } catch (InvalidPortException | InvalidEndpointException e) {
            log.error("init minio failed " + e.getMessage());
        }
    }

    /**
     * 判断 bucket是否存在
     *
     * @param bucketName
     * @return
     */
    public boolean bucketExists(String bucketName) {
        try {
            return instance.bucketExists(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建 bucket
     *
     * @param bucketName
     */
    public void makeBucket(String bucketName) {
        try {
            boolean isExist = instance.bucketExists(bucketName);
            if (!isExist) {
                instance.makeBucket(bucketName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件上传
     *
     * @param bucketName
     * @param objectName
     * @param filename
     */
    public void putObject(String bucketName, String objectName, String filename) {
        try {
            makeBucket(bucketName);
            instance.putObject(bucketName, objectName, filename, null);
        } catch (Exception e) {
            throw new BIZException("upload file failed " + e.getMessage());
        }
    }

    /**
     * 文件上传
     *
     * @param bucketName
     * @param objectName
     * @param stream
     * @param contentType
     */
    public void putObject(String bucketName, String objectName, InputStream stream, String contentType) {
        try {
            makeBucket(bucketName);
            instance.putObject(bucketName, objectName, stream, contentType);
        } catch (Exception e) {
            throw new BIZException("upload file failed " + e.getMessage());
        }
    }

    /**
     * 文件上传
     *
     * @param bucketName
     * @param objectName
     * @param stream
     */
    public void putObject(String bucketName, String objectName, InputStream stream) {
        putObject(bucketName, objectName, stream, FileUtil.getMimeType(objectName));
    }

    /**
     * 删除文件
     *
     * @param bucketName
     * @param objectName
     */
    public void removeObject(String bucketName, String objectName) {
        try {
            instance.removeObject(bucketName, objectName);
        } catch (Exception e) {
            throw new BIZException("remove file failed " + e.getMessage());
        }
    }

    /**
     * 获取文件链接
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public String genShareLink(String bucketName, String objectName) {
        return genShareLink(bucketName, objectName, 60 * 60 * 2);
    }

    /**
     * 获取文件链接
     *
     * @param bucketName
     * @param objectName
     * @param expires
     * @return
     */
    public String genShareLink(String bucketName, String objectName, int expires) {

        String url =
                null;
        try {
            url = instance.getPresignedObjectUrl(
                    Method.GET,
                    bucketName,
                    objectName,
                    expires, null);
        } catch (Exception e) {
            throw new BIZException("get file share link failed " + e.getMessage());
        }
        return url;
    }

    /**
     * 流下载
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public InputStream getObject(String bucketName, String objectName) {
        try {
            InputStream object = instance.getObject(bucketName, objectName);

            return object;
        } catch (Exception e) {
            throw new BIZException("get file stream failed " + e.getMessage());
        }
    }

    /**
     * 文件下载
     *
     * @param bucketName
     * @param objectName
     * @param fileName
     */
    public void getObject(String bucketName, String objectName, String fileName) {
        try {
            instance.getObject(bucketName, objectName, fileName);
        } catch (Exception e) {
            throw new BIZException("get file stream failed " + e.getMessage());
        }
    }

    /**
     * meta data
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public ObjectStat getObjectStat(String bucketName, String objectName) {
        try {
            ObjectStat objectStat = instance.statObject(bucketName, objectName);

            return objectStat;
        } catch (Exception e) {
            throw new BIZException("get file stream failed " + e.getMessage());
        }
    }
}